App.require(function () {
    var app = App.getCurrent();

    app.definePage("strdatarangeselectyearmonth", {
        getDomObj: function () {
            this.attachDom(".select-hour-start", "selectHourStart")
                .attachDom(".select-minute-start", "selectMinuteStart")
                .attachDom(".select-hour-end", "selectHourEnd")
                .attachDom(".select-minute-end", "selectMinuteEnd")
                .attachDom(".select-hour-start ul", "selectHourUlStart")
                .attachDom(".select-minute-start ul", "selectMinuteUlStart")
                .attachDom(".select-hour-end ul", "selectHourUlEnd")
                .attachDom(".select-minute-end ul", "selectMinuteUlEnd")
                .attachDom(".select-hour-start li.selected", "hourSelectedStart")
                .attachDom(".select-minute-start li.selected", "minuteSelectedStart")
                .attachDom(".select-hour-end li.selected", "hourSelectedEnd")
                .attachDom(".select-minute-end li.selected", "minuteSelectedEnd")
                .attachEvent("selectHourStart", "click", this.clickStartHourHandler, false)
                .attachEvent("selectHourStart", "mousewheel", this.wheelStartHourHandler, false)
                .attachEvent("selectHourStart", "DOMMouseScroll", this.scrollStartHourHandler, false)
                .attachEvent("selectHourStart", "iconclick", this.iconClickStartHourHandler, false)
                .attachEvent("selectMinuteStart", "mousewheel", this.wheelStartMinuteHandler, false)
                .attachEvent("selectMinuteStart", "DOMMouseScroll", this.scrollStartMinuteHandler, false)
                .attachEvent("selectMinuteStart", "iconclick", this.iconClickStartMinuteHandler, false)
                .attachEvent("selectMinuteStart", "click", this.clickStartMinuteHandler, false)
                .attachEvent("selectHourEnd", "click", this.clickEndHourHandler, false)
                .attachEvent("selectHourEnd", "mousewheel", this.wheelEndHourHandler, false)
                .attachEvent("selectHourEnd", "DOMMouseScroll", this.scrollEndHourHandler, false)
                .attachEvent("selectHourEnd", "iconclick", this.iconClickEndHourHandler, false)
                .attachEvent("selectMinuteEnd", "mousewheel", this.wheelEndMinuteHandler, false)
                .attachEvent("selectMinuteEnd", "DOMMouseScroll", this.scrollEndMinuteHandler, false)
                .attachEvent("selectMinuteEnd", "iconclick", this.iconClickEndMinuteHandler, false)
                .attachEvent("selectMinuteEnd", "click", this.clickEndMinuteHandler, false)
        },
        operateHour: function (num, str) {
            var time = this.data.startYDate, 
                selectHourDom = this.domList.selectHourStart, 
                hourSelectedDom = this.domList.hourSelectedStart,
                domStr = "hourSelectedStart",
                hourSelectUl = this.domList.selectHourUlStart,
                minYear = this.data.startMinYear,
                maxYear = this.data.startMaxYear;

            if (str !== "start") {
                time = this.data.endYDate;
                selectHourDom = this.domList.selectHourEnd;
                hourSelectedDom = this.domList.hourSelectedEnd;
                domStr = "hourSelectedEnd";
                hourSelectUl = this.domList.selectHourUlEnd;
                minYear = this.data.endMinYear;
                maxYear = this.data.endMaxYear;
            }

            if (num > 0) {
                if (time.year < maxYear - 1) time.year++;
            }
            else {
                if (time.year > minYear) time.year--;
            }
            selectHourDom.querySelector("ul").style.transform = 'translateY(' + (3 - time.year + minYear) * 28 + 'px)';
            hourSelectedDom.classList.remove("selected");
            var target = hourSelectUl.children[time.year - minYear + 3];
            target.classList.add("selected");
            this.domList[domStr] = target;

            if (str == "start") this.updateSelectYearAndMonth(true, false, false, false);
            else this.updateSelectYearAndMonth(false, false, true, false);
            this.parent.staticPage.changeYearMonth(str);
        },
        operateMinute: function (num, str) {
            var time = this.data.startYDate, 
                selectMinuteDom = this.domList.selectMinuteStart, 
                minuteSelectedDom = this.domList.minuteSelectedStart,
                domStr = "minuteSelectedStart",
                minuteSelectUl = this.domList.selectMinuteUlStart,
                minMonth = this.data.startMinMonth,
                maxMonth = this.data.startMaxMonth;

            if (str !== "start") {
                time = this.data.endYDate;
                selectMinuteDom = this.domList.selectMinuteEnd;
                minuteSelectedDom = this.domList.minuteSelectedEnd;
                domStr = "minuteSelectedEnd";
                minuteSelectUl = this.domList.selectMinuteUlEnd;
                minMonth = this.data.endMinMonth;
                maxMonth = this.data.endMaxMonth;
            }
            if (num > 0) {
                if (time.month < maxMonth - 1) time.month++;
            }
            else {
                if (time.month > minMonth) time.month--;
            }
            selectMinuteDom.querySelector("ul").style.transform = 'translateY(' + (3 - time.month + minMonth) * 28 + 'px)';
            minuteSelectedDom.classList.remove("selected");
            var target = minuteSelectUl.children[time.month - minMonth + 3];
            target.classList.add("selected");
            this.domList[domStr] = target;

            if (str == "start") this.updateSelectYearAndMonth(true, true, true, false);
            else this.updateSelectYearAndMonth(true, false, true, true);
            this.parent.staticPage.changeYearMonth(str);
        },
        _operationHour: function (component, str) {
            if (component.dataset.action == "down") {
                this.operateHour(1, str);
            }
            else if (component.dataset.action == "up") {
                this.operateHour(-1, str);
            }
        },
        _clickHourTarget: function (target, str) {
            if (target.nodeName.toUpperCase() == "LI") {
                var time = this.data.startYDate, hourSelected = this.domList.hourSelectedStart, 
                    domStr = "hourSelectedStart", minYear = this.data.startMinYear;
                if (str !== "start") {
                    time = this.data.endYDate;
                    hourSelected = this.domList.hourSelectedEnd;
                    domStr = "hourSelectedEnd";
                    minYear = this.data.endMinYear;
                }
                time.year = parseInt(target.textContent);
                target.parentNode.style.transform = 'translateY(' + (3 - (time.year - minYear)) * 28 + 'px)';
                hourSelected.classList.remove("selected");
                target.classList.add("selected");
                this.domList[domStr] = target;

                if (str == "start") this.updateSelectYearAndMonth(true, false, false, false);
                else this.updateSelectYearAndMonth(false, false, true, false);
                this.parent.staticPage.changeYearMonth(str);
            }
        },
        _clickMinuteTarget: function (target, str) {
            if (target.nodeName.toUpperCase() == "LI") {
                var time = this.data.startYDate, minuteSelected = this.domList.minuteSelectedStart, 
                    domStr = "minuteSelectedStart", minMonth = this.data.startMinMonth;
                if (str !== "start") {
                    time = this.data.endYDate;
                    minuteSelected = this.domList.minuteSelectedEnd;
                    domStr = "minuteSelectedEnd";
                    minMonth = this.data.endMinMonth;
                }
                time.month = parseInt(target.textContent);
                target.parentNode.style.transform = 'translateY(' + (3 - time.month + minMonth) * 28 + 'px)';
                minuteSelected.classList.remove("selected");
                target.classList.add("selected");
                this.domList[domStr] = target;

                if (str == "start") this.updateSelectYearAndMonth(true, true, true, false);
                else this.updateSelectYearAndMonth(true, false, true, true);
                this.parent.staticPage.changeYearMonth(str);
            }
        },
        updateSelectYearAndMonth: function (isStartYear, isStartMonth, isEndYear, isEndMonth) {
            var data = this.data;
            this.createMinMaxYearAndMonth();

            if (!isStartYear) {
                if (data.startYDate.year < data.startMinYear) data.startYDate.year = data.startMinYear;
                else if (data.startYDate.year > data.startMaxYear) data.startYDate.year = data.startMaxYear;
                data.selectStartHoursHtml = this.computedHours(data.startYDate.year, "start");
                var dom = this.domList.selectHourUlStart;
                dom.innerHTML = '<li></li><li></li><li></li>' + data.selectStartHoursHtml + '<li></li><li></li><li></li>';
                dom.style.transform = 'translateY(' + (3 - (data.startYDate.year - data.startMinYear)) * 28 + 'px)';
                this.domList.hourSelectedStart = dom.querySelector(".selected");
            }

            if (!isStartMonth) {
                if (data.startYDate.month < data.startMinMonth) data.startYDate.month = data.startMinMonth;
                else if (data.startYDate.month > data.startMaxMonth) data.startYDate.month = data.startMaxMonth;
                data.selectStartMinutesHtml = this.computedMinutes(data.startYDate.month, "start");
                var dom = this.domList.selectMinuteUlStart;
                dom.innerHTML = '<li></li><li></li><li></li>' + data.selectStartMinutesHtml + '<li></li><li></li><li></li>';
                dom.style.transform = 'translateY(' + (3 - (data.startYDate.month - data.startMinMonth)) * 28 + 'px)';
                this.domList.minuteSelectedStart = dom.querySelector(".selected");
            }

            if (!isEndYear) {
                if (data.endYDate.year < data.endMinYear) data.endYDate.year = data.endMinYear;
                else if (data.endYDate.year > data.endMaxYear) data.endYDate.year = data.endMaxYear;
                data.selectNextHoursHtml = this.computedHours(data.endYDate.year, "end");
                var dom = this.domList.selectHourUlEnd;
                dom.innerHTML = '<li></li><li></li><li></li>' + data.selectNextHoursHtml + '<li></li><li></li><li></li>';
                dom.style.transform = 'translateY(' + (3 - (data.endYDate.year - data.endMinYear)) * 28 + 'px)';
                this.domList.hourSelectedEnd = dom.querySelector(".selected");
            }

            if (!isEndMonth) {
                if (data.endYDate.month < data.endMinMonth) data.endYDate.month = data.endMinMonth;
                else if (data.endYDate.month > data.endMaxMonth) data.endYDate.month = data.endMaxMonth;
                data.selectNextMinutesHtml = this.computedMinutes(data.endYDate.month, "end");
                var dom = this.domList.selectMinuteUlEnd;
                dom.innerHTML = '<li></li><li></li><li></li>' + data.selectNextMinutesHtml + '<li></li><li></li><li></li>';
                dom.style.transform = 'translateY(' + (3 - (data.endYDate.month - data.endMinMonth)) * 28 + 'px)';
                this.domList.minuteSelectedEnd = dom.querySelector(".selected");
            }
        },
        clickStartHourHandler: function (ev) {
            this._clickHourTarget(ev.target, "start");
        },
        clickEndHourHandler: function (ev) {
            this._clickHourTarget(ev.target, "end");
        },
        wheelStartHourHandler: function (ev) {
            ev.preventDefault();
            ev.stopPropagation();
            this.operateHour(ev.wheelDelta, "start");
        },
        scrollStartHourHandler: function (ev) {
            ev.preventDefault();
            ev.stopPropagation();
            this.operateHour(-ev.delta, "start");
        },
        iconClickStartHourHandler: function (ev) {
            this._operationHour(ev.detail.component, "start");
        },
        _operationMinute: function (component, str) {
            if (component.dataset.action == "down") {
                this.operateMinute(1, str);
            }
            else if (component.dataset.action == "up") {
                this.operateMinute(-1, str);
            }
        },
        wheelStartMinuteHandler: function (ev) {
            ev.preventDefault();
            ev.stopPropagation();
            this.operateMinute(ev.wheelDelta, "start");
        },
        scrollStartMinuteHandler: function (ev) {
            ev.preventDefault();
            ev.stopPropagation();
            this.operateMinute(-ev.delta, "start");
        },
        iconClickStartMinuteHandler: function (ev) {
            this._operationMinute(ev.detail.component, "start");
        },
        clickStartMinuteHandler: function (ev) {
            this._clickMinuteTarget(ev.target, "start");
        },
        wheelEndHourHandler: function (ev) {
            ev.preventDefault();
            ev.stopPropagation();
            this.operateHour(ev.wheelDelta, "end");
        },
        scrollEndHourHandler: function (ev) {
            ev.preventDefault();
            ev.stopPropagation();
            this.operateHour(-ev.delta, "end");
        },
        iconClickEndHourHandler: function (ev) {
            this._operationHour(ev.detail.component, "end");
        },
        wheelEndMinuteHandler: function (ev) {
            ev.preventDefault();
            ev.stopPropagation();
            this.operateMinute(ev.wheelDelta, "end");
        },
        scrollEndMinuteHandler: function (ev) {
            ev.preventDefault();
            ev.stopPropagation();
            this.operateMinute(-ev.delta, "end");
        },
        iconClickEndMinuteHandler: function (ev) {
            this._operationMinute(ev.detail.component, "end");
        },
        clickEndMinuteHandler: function (ev) {
            this._clickMinuteTarget(ev.target, "end");
        },
        createMinMaxYearAndMonth: function () {
            var data = this.data;

            data.startMinYear = data.minDate.year ? data.minDate.year : 1950;
            data.startMaxYear = data.endYDate.year + 1;
            data.endMinYear = data.startYDate.year;
            data.endMaxYear = data.maxDate.year ? data.maxDate.year + 1 : 2100;

            if (data.minDate.year) data.startMinMonth = data.startYDate.year === data.minDate.year ? data.minDate.month : 1;
            else data.startMinMonth = 1;
            data.startMaxMonth = data.startYDate.year === data.endYDate.year ? data.endYDate.month + 1 : 13;

            data.endMinMonth = data.endYDate.year === data.startYDate.year ? data.startYDate.month : 1;
            if (data.maxDate.year) data.endMaxMonth = data.endYDate.year === data.maxDate.year ? data.maxDate.month + 1 : 13;
            else data.endMaxMonth = 13;
        },
        render: function (next) {
            var data = this.data, parentData = this.parent.data;
            data.startYDate = parentData.startYDate;
            data.endYDate = parentData.endYDate;
            data.minDate = parentData.minDate;
            data.maxDate = parentData.maxDate;
            this.createMinMaxYearAndMonth();
            data.selectStartHoursHtml = this.computedHours(data.startYDate.year, "start");
            data.selectStartMinutesHtml = this.computedMinutes(data.startYDate.month, "start");
            data.selectNextHoursHtml = this.computedHours(data.endYDate.year, "end");
            data.selectNextMinutesHtml = this.computedMinutes(data.endYDate.month, "end");
            this.data.startHourStyle = "transform: translateY(" + (3 - (data.startYDate.year - data.startMinYear)) * 28 + "px)";
            this.data.startMinuteStyle = "transform: translateY(" + (3 - (data.startYDate.month - data.startMinMonth)) * 28 + "px)";
            this.data.endHourStyle = "transform: translateY(" + (3 - (data.endYDate.year - data.endMinYear)) * 28 + "px)";
            this.data.endMinuteStyle = "transform: translateY(" + (3 - (data.endYDate.month - data.endMinMonth)) * 28 + "px)";
            this.fetch("./index.html", function (text) {
                next(this.renderHTML(text));
            })
        },
        computedHours: function (hour, str) {
            var html = "", data = this.data;
            var startYear = data.startMinYear, endYear = data.startMaxYear;
            if (str !== "start") {
                startYear = data.endMinYear;
                endYear = data.endMaxYear;
            }
            for (var i = startYear; i < endYear; i++) {
                var str = i;
                if (i == hour) html += '<li class="selected">' + str + '</li>';
                else html += '<li>' + str + '</li>';
            }
            return html;
        },
        computedMinutes: function (minute, str) {
            var html = "", data = this.data;
            var startMonth = data.startMinMonth, endMonth = data.startMaxMonth;
            if (str !== "start") {
                startMonth = data.endMinMonth;
                endMonth = data.endMaxMonth;
            }
            for (var i = startMonth; i < endMonth; i++) {
                var str = ("0" + i).slice(-2);
                if (i == minute) html += '<li class="selected">' + str + '</li>';
                else html += '<li>' + str + '</li>';
            }
            return html;
        }
    })
})